package com.ruoyi.common.utils;



import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author tswsoft
 * @version 1.0.0
 * @deprecate LocalDateTime格式转化工具类
 * @date
 */
public class LocalDateTimeUtils {

    private static final ConcurrentMap<String, DateTimeFormatter> FORMATTER_CACHE = new ConcurrentHashMap<>();

    private static final int PATTERN_CACHE_SIZE = 100;

    public static final String PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_YYYY_MM_DD_T_HH_MM_SS = "yyyy-MM-ddTHH:mm:ss";
    public static final String PATTERN_YYYY_MM_DD = "yyyy-MM-dd";
    public static final String PATTERN_YYYY_MM = "yyyy-MM";
    public static final String PATTERN_YYMM = "yyMM";
    public static final String PATTERN_MM_DD = "MM-dd";

    public static final String PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String PATTERN_YYYYMMDD = "yyyyMMdd";
    public static final String PATTERN_YYYYMM = "yyyyMM";
    public static final String PATTERN_YYMMDD = "yyMMdd";
    public static final String PATTERN_MMDD = "MMdd";
    public static final String PATTERN_HHMMSS = "HHmmss";

    /**
     * 在缓存中创建DateTimeFormatter
     *
     * @param pattern 格式
     */
    private static DateTimeFormatter createCacheFormatter(String pattern) {
        if (pattern == null || pattern.length() == 0) {
            throw new IllegalArgumentException("Invalid pattern specification");
        }
        DateTimeFormatter formatter = FORMATTER_CACHE.get(pattern);
        if (formatter == null) {
            if (FORMATTER_CACHE.size() < PATTERN_CACHE_SIZE) {
                formatter = DateTimeFormatter.ofPattern(pattern);
                DateTimeFormatter oldFormatter = FORMATTER_CACHE.putIfAbsent(pattern, formatter);
                if (oldFormatter != null) {
                    formatter = oldFormatter;
                }
            }
        }
        return formatter;
    }

    public static LocalDateTime dateToLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    public static LocalDate dateToLocalDate(Date date) {
        return dateToLocalDateTime(date).toLocalDate();
    }

    public static LocalTime dateToLocalTime(Date date) {
        return dateToLocalDateTime(date).toLocalTime();
    }

    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date localDateToDate(LocalDate localDate) {
        Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public static Date localTimeToDate(LocalTime localTime) {
        LocalDate localDate = LocalDate.now();
        Instant instant = LocalDateTime.of(localDate, localTime).atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    /**
     * localDateTime转换为格式化时间
     *
     * @param localDateTime localDateTime
     * @param pattern 格式
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDateTime.format(formatter);
    }

    public static String format(LocalDateTime localDateTime) {
        return format(localDateTime, PATTERN_YYYY_MM_DD_HH_MM_SS);
    }

    public static String format(LocalDate localDate, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDate.format(formatter);
    }

    public static String format(LocalDate localDate) {
        return format(localDate, PATTERN_YYYY_MM_DD);
    }

    /**
     * 格式化字符串转为LocalDateTime
     *
     * @param time 格式化时间 默认 yyyy-MM-dd HH:mm:ss
     */
    public static LocalDateTime parseLocalDateTime(String time) {
        DateTimeFormatter formatter = createCacheFormatter(PATTERN_YYYY_MM_DD_HH_MM_SS);
        return LocalDateTime.parse(time, formatter);
    }

    /**
     * 格式化字符串转为LocalDateTime
     *
     * @param time 格式化时间
     * @param pattern 格式
     */
    public static LocalDateTime parseLocalDateTime(String time, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalDateTime.parse(time, formatter);
    }

    public static LocalDate parseLocalDate(String time, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalDate.parse(time, formatter);
    }

    public static LocalDateTime getFirstDayOfMonth(String yearMonthDateStr, int monthNum) {
        YearMonth yearMonth = YearMonth.parse(yearMonthDateStr);
        LocalDate localDate = LocalDate.of(yearMonth.getYear(), yearMonth.getMonth(), 1).plusMonths(monthNum);
        return localDate.atStartOfDay(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 获取某年某月的第一天
     * @param year
     * @param month
     * @return
     */
    public static LocalDate getFirstDayOfMonth(Integer year,Integer month) {
        return LocalDate.of(year, month, 1);
    }

    /**
     * 获取某年某月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static LocalDate getLastDayOfMonth(Integer year,Integer month) {
        LocalDate localDate = LocalDate.of(year, month, 1);
        return localDate.with(TemporalAdjusters.lastDayOfMonth());
    }

    public static String getDayNameOfWeek(LocalDateTime localDateTime) {
        String[] daysOfWeek = new String[]{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
        return daysOfWeek[localDateTime.getDayOfWeek().getValue() - 1];
    }

    /**
     * 将LocalDateTime转为自定义的时间格式的字符串
     * @param localDateTime
     * @param format
     * @return
     */
    public static String getDateTimeAsString(LocalDateTime localDateTime, String format) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return localDateTime.format(formatter);
    }

    /**
     * 将long类型的timestamp转为LocalDateTime
     * @param timestamp
     * @return
     */
    public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 将long类型的timestamp转为LocalDateTime
     * @param timestamp
     * @return
     */
    public static LocalDateTime getDateTimeOfTimestampSeconds(long timestampSeconds) {
        Instant instant = Instant.ofEpochSecond(timestampSeconds);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 将LocalDateTime转为long类型的timestamp
     * @param localDateTime
     * @return
     */
    public static long getTimestampOfDateTime(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return instant.toEpochMilli();
    }

    /**
     * 将LocalDateTime转为long类型的timestamp seconds
     * @param localDateTime
     * @return
     */
    public static long getTimestampSecondOfDateTime(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).toEpochSecond();
    }

    /**
     * 将某时间字符串转为自定义时间格式的LocalDateTime
     * @param time
     * @param format
     * @return
     */
    public static LocalDateTime parseStringToDateTime(String time, String format) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(time, df);
    }

    /**
     * 获取两个日期的天数差(天数相减，不包含最后那天)
     * @param startDate
     * @param endDate
     * @return
     */
    public static Long getBetweenDays(LocalDate startDate, LocalDate endDate) {
        Duration duration = Duration.between(startDate.atStartOfDay(),endDate.atStartOfDay());
        return duration.toDays();
    }
}